---
title: "Column Headers"
description: "Column Headers provide a header name and basic functionality for each column in the $framework table. Use the provided component or create a custom Column Header."
---

Each Column has a Column Header providing a Header Name and typically functions such as Column Resize, Row Sorting and Row Filtering.

## Header Name

When no header name is provided, the grid will derive the header name from the provided `field`. The grid expects the field value to use Camel Case and will insert spaces between word breaks to build a readable header name.

```{% frameworkTransform=true suppressFrameworkContext=true spaceBetweenProperties=true %}
const gridOptions = {
    columnDefs: [
        // header name will be 'Athlete'
        { field: 'athlete' },
        // header name will be 'First Name'
        { field: 'firstName' },
        // header name will be 'foo'
        { headerName: 'foo', field: 'bar' }
    ]
}
```

## Header Value Getters

Use `headerValueGetter` instead of `colDef.headerName` to provide column header names dynamically.

{% apiDocumentation source="column-properties/properties.json" section="header" names=["headerValueGetter"] /%}

The parameters for `headerValueGetter` differ from a [Cell Value Getter](./value-getters) as follows:

* Only one of column or columnGroup will be present, depending on whether it's a column or a column group.
* Parameter `location` allows you to have different column names depending on where the column is appearing, eg you might want to have a different name when the column is in the column drop zone or the toolbar.

See the [Column Tool Panel Example](./tool-panel-columns/#columns-tool-panel-example) for an example of `headerValueGetter` used in different locations, where you can change the header name depending on where the name appears.


## Header Styling

This section will show different ways of manually styling the Grid Header.

### Header Style

Used to provide CSS styles directly (not using a class) to the header. Can be either an object
of CSS styles, or a function returning an object of CSS styles.

{% apiDocumentation source="column-properties/properties.json" section="styling" names=["headerStyles"] /%}

```{% frameworkTransform=true spaceBetweenProperties=true %}
const gridOptions = {
    columnDefs: [
        // applies to header and floating filter header
        {
            headerName: 'Static Styles',
            field: 'static',
            headerStyle: { color: 'red', 'background-color': 'green' }
        },
        {
            headerName: 'Dynamic Styles',
            field: 'dynamic',
            headerStyle: params => {
                // only style floating filter
                if (params.floatingFilter) {
                    return { backgroundColor: 'green' };
                }
                return null;
            }
        },
    ]
}
```

### Header Class

Provides a class for the header. Can be a string (a class), array of strings
(array of classes), or a function (that returns a string or an array of strings).

{% apiDocumentation source="column-properties/properties.json" section="styling" names=["headerClass"] /%}

```{% frameworkTransform=true spaceBetweenProperties=true %}
const gridOptions = {
    columnDefs: [
        {
            headerName: 'Static Class',
            field: 'static',
            headerClass: 'my-class'
        },
        {
            headerName: 'Static Array of Classes',
            field: 'staticArray',
            headerClass: ['my-class1','my-class2'],
        },
        {
            headerName: 'Function Returns String',
            field: 'function',
            headerClass: params => {
                return params.columnGroup ? 'my-custom-column-group' : 'my-custom-column';
            },
        }
    ]
}
```

### Style Interface

{% interfaceDocumentation interfaceName="AbstractColDef" names=["headerStyle", "headerClass" ] /%}

### Combined Example

Below shows both headerStyle and headerClass in a full working example. The example demonstrates the following:

- **Athlete Details**: uses `headerStyle` static object.
- **Athlete**: uses `headerStyle` static object functions. This also causes the floating filter to be styled.
- **Country**: uses `headerStyle` function callback. This allows to set a different background color for the header and floating filter.
- **Sport**: uses `headerClass` to add the `sport-header` class to the header.
- **Medal Details**: uses `headerStyle` callback function to toggle different styles when the group is expanded or collapsed.


{% gridExampleRunner title="Header Styling" name="header-styles" /%}

## Header Height

These properties can be used to change the different heights used in the headers.

{% apiDocumentation source="grid-options/properties.json" section="headers" /%}

As you can see in the example below, if you change any of the header heights, this change will be reflected automatically. Note how if the value is cleared (set to `undefined`), it might reuse other values. To see all the interactions check the properties descriptions at the top of the page.


{% gridExampleRunner title="Dynamic Header Height" name="dynamic-height" /%}

## Auto Header Height

The column header row can have its height set automatically based on the content of the header cells. This is most useful when used together with [Custom Header Components](./column-headers/#custom-component/) or when using the `wrapHeaderText` column property.

To enable this, set `autoHeaderHeight=true` on the column definition you want to adjust the header height for. If more than one column has this property enabled, then the header row will be sized to the maximum of these columns' header cells so no content overflows.

The example below demonstrates using the `autoHeaderHeight` property in conjunction with the `wrapHeaderText` property, so that long column names are fully displayed.

* Note that the long column header names wrap onto another line.
* Try making a column smaller by dragging the resize handle on the column header, observe that the header will expand so the full header content is still visible.

{% gridExampleRunner title="Auto Header Height" name="auto-height" /%}

## Hide Padded Column Headers

When using column groups the grid adds padding to columns to ensure the column tree is balanced. When a column with a deeper tree is hidden, this can lead to
header rows consisting entirely of padding. Set the `hidePaddedHeaderRows` grid option to `true` to hide rows consisting of only padding.

{% gridExampleRunner title="Hide Padded Header Rows" name="hide-padded-header-rows" /%}

The example above demonstrates a grid with hidden column groups, causing the grid headers to be taller than necessary when the parent group is collapsed.

## Selecting Components

By default the grid uses the provided Header Component. To use a Custom Header Component set `headerComponent` on the Column Definition.

{% partial file="./_column-def-javascript.mdoc" /%}
{% partial file="./_column-def-vue.mdoc" /%}

See [Registering Components](./components/) for an overview of registering components.


## Provided Component

Most applications will use the Provided Header Component. It provides functionality such as Sorting, Filtering and Column Menu.

You can provide an HTML template to the Default Header Component for simple layout changes. This is the default template used in AG Grid:

```html
<div class="ag-cell-label-container" role="presentation">
    <span data-ref="eMenu" class="ag-header-icon ag-header-cell-menu-button" aria-hidden="true"></span>
    <span data-ref="eFilterButton" class="ag-header-icon ag-header-cell-filter-button" aria-hidden="true"></span>
    <div data-ref="eLabel" class="ag-header-cell-label" role="presentation">
        <span data-ref="eText" class="ag-header-cell-text"></span>
        <span data-ref="eFilter" class="ag-header-icon ag-header-label-icon ag-filter-icon" aria-hidden="true"></span>
        <span data-ref="eSortOrder" class="ag-header-icon ag-header-label-icon ag-sort-order" aria-hidden="true"></span>
        <span data-ref="eSortAsc" class="ag-header-icon ag-header-label-icon ag-sort-ascending-icon" aria-hidden="true"></span>
        <span data-ref="eSortDesc" class="ag-header-icon ag-header-label-icon ag-sort-descending-icon" aria-hidden="true"></span>
        <span data-ref="eSortNone" class="ag-header-icon ag-header-label-icon ag-sort-none-icon" aria-hidden="true"></span>
    </div>
</div>
```

When you provide your own template, everything should work as expected as long as you re-use the same `data-ref` attribute names.

| Ref | Description |
|-|-|
| `eMenu` | The container where the column menu icon will appear to enable opening the column menu (in AG Grid Community, this is only used when `columnMenu = 'legacy'`). |
| `eFilterButton` | The container where the column filter icon will appear to enable opening the filter (not used when `columnMenu = 'legacy'`). |
| `eLabel` | The container where there is going to be an onClick mouse listener to trigger the sort. |
| `eText` | The text displayed on the column. |
| `eFilter` | The container with the icon that will appear if the user filters this column (only used when `columnMenu = 'legacy'` or `suppressHeaderFilterButton = true`). |
| `eSortOrder` | If multiple columns are sorted, this shows the index that represents the position of this column in the order. |
| `eSortAsc` | If the column is sorted ascending, this shows the ascending icon. |
| `eSortDesc` | If the column is sorted descending, this shows the descending icon. |
| `eSortNone` | If no sort is applied, this shows the no sort icon. Note this icon by default is empty. |

The `data-ref` parameters are used by the grid to identify elements to add functionality to. If you leave an element out of your template, the functionality will not be added. For example if you do not specify `eLabel` then the column will not react to click events for sorting.

{% note %}
Templates are not meant to let you configure icons. If you are looking to change the icons, see [Custom Icons](./custom-icons/) for more information.
{% /note %}

Set the template using `colDef.headerComponentParams`. Set on the `defaultColDef` grid option to set for all Columns.

```{% frameworkTransform=true %}
const gridOptions = {
    defaultColDef: {
        width: 100,
        headerComponentParams: {
            template:
                `<div class="ag-cell-label-container" role="presentation">
                  <span data-ref="eMenu" class="ag-header-icon ag-header-cell-menu-button"></span>
                  <span data-ref="eFilterButton" class="ag-header-icon ag-header-cell-filter-button"></span>
                  <div data-ref="eLabel" class="ag-header-cell-label" role="presentation">
                    <span data-ref="eSortOrder" class="ag-header-icon ag-sort-order"></span>
                    <span data-ref="eSortAsc" class="ag-header-icon ag-sort-ascending-icon"></span>
                    <span data-ref="eSortDesc" class="ag-header-icon ag-sort-descending-icon"></span>
                    <span data-ref="eSortNone" class="ag-header-icon ag-sort-none-icon"></span>
                    ** <span data-ref="eText" class="ag-header-cell-text" role="columnheader"></span>
                    <span data-ref="eFilter" class="ag-header-icon ag-filter-icon"></span>
                  </div>
                </div>`
        }
    }
}
```

Note that specifying your own templates is compatible with other configurations:

* `suppressHeaderFilterButton` is specified in: **Athlete**, **Country**, **Date** and **Bronze** columns
* `sortable=false` is specified in: **Age**, **Year**, **Sport**, **Silver** and **Total** columns
* **Gold** is the only column that doesn't have `sortable=false` or `suppressHeaderFilterButton`

{% gridExampleRunner title="Header template" name="header-template" /%}

## Inner Header Component

When using the Header Component, the `agColumnHeader` component will display the header name,
adjacent to any configured menu, filter, and checkbox.

This text value can be overridden with a [Custom Component](./components/) by setting the `innerHeaderComponent` and `innerHeaderComponentParams` properties
on the `headerComponentParams` property. This is useful when you only need to implement a Component to customise the **Column Name** without having to reimplement
the whole header functionality (sorting, filter, menu, etc...).

{% if isFramework("javascript", "angular", "react") %}
```js
colDef = {
    ...
    headerComponentParams : {
        innerHeaderComponent: MyInnerHeaderComponent,
        innerHeaderComponentParams: {
            currencySymbol: '£' // the pound symbol will be placed into params
        }
    }
}
```
{% /if %}

{% if isFramework("vue") %}
```js
colDef = {
    ...
        headerComponentParams : {
        innerHeaderComponent: 'MyInnerHeaderComponent',
        innerHeaderComponentParams: {
            currencySymbol: '£' // the pound symbol will be placed into params
        }
    }
}
```
{% /if %}

{% gridExampleRunner title="Custom Inner Header Component" name="inner-header-component" /%}

{% if isFramework("javascript", "angular") %}
Implement this interface to provide a custom inner header component.
{% /if %}
{% if isFramework("javascript") %}
### IInnerHeaderComponent
{% interfaceDocumentation interfaceName="IInnerHeaderComponent" config={"asCode":true } /%}
{% /if %}
{% if isFramework("angular") %}
### IInnerHeaderAngularComp
{% interfaceDocumentation interfaceName="IInnerHeaderAngularComp" config={"asCode":true } /%}
{% /if %}
{% if isFramework("javascript", "angular") %}
### IHeaderParams
{% interfaceDocumentation interfaceName="IHeaderParams" exclude=["template"] config={ "description": "" } /%}
{% /if %}
{% if isFramework("react") %}
```ts
const CustomInnerHeaderComponent = (props: CustomInnerHeaderProps) => {
    return <div>{props.displayName}</div>;
};
```
The following props are passed to the Custom Component (`CustomInnerHeaderProps` interface).
### CustomInnerHeaderProps
{% interfaceDocumentation interfaceName="CustomInnerHeaderProps" config={ "description": "" } /%}
{% /if %}
{% if isFramework("vue") %}
Any valid Vue component can be a custom inner header component, however it must implement the `IHeader` interface:

### IHeader
{% interfaceDocumentation interfaceName="IHeader" config={"asCode":true } /%}
{% /if %}


## Custom Component

Column Headers by default use the Provided Header Component. The default can be overridden with Custom Header Component. This example shows a Custom Header Component. Note the following:

* Column moving and resizing works without custom logic.
* `suppressHeaderFilterButton=true` is used to suppress the filter menu.
* `sortable=false` is used to suppress sorting.
* The menu icon is configurable.

{% gridExampleRunner title="Header component" name="header-component" /%}

{% if isFramework("javascript", "angular", "vue") %}
The interface for a custom header component is:
{% /if %}

{% partial file="./_component-interface-javascript.mdoc" /%}
{% partial file="./_component-interface-angular.mdoc" /%}
{% partial file="./_component-interface-vue.mdoc" /%}

{% if isFramework("javascript") %}
The `init(params)` method takes a params object with the items listed below.
{% /if %}

{% if isFramework("angular") %}
The `agInit(params)` method takes a params object with the items listed below.
{% /if %}

{% if isFramework("vue") %}
When a Vue component is instantiated the grid will make the grid APIs, a number of utility methods as well as the cell and
row values available to you via `this.params` - the interface for what is provided is documented below.
{% /if %}

{% if isFramework("react") %}
The following props are passed to the Custom Component (`CustomHeaderProps` interface).
{% /if %}

{% if isFramework("javascript", "angular", "vue") %}
{% interfaceDocumentation interfaceName="IHeaderParams" exclude=["template"] config={ "description": "" } /%}
{% /if %}

{% if isFramework("react") %}
{% interfaceDocumentation interfaceName="CustomHeaderProps" exclude=["template"] config={ "description": "" } /%}
{% /if %}

### Responsibilities

The grid provides the following features that should not be implemented by Custom Header Components:

* [**Resizing:**](./column-sizing/) When enabled, the grid will put an invisible widget to be grabbed by the mouse for resizing.
* [**Header Checkbox Selection:**](./row-selection-multi-row/#selecting-all-rows) When enabled, the grid displays a checkbox for 'select all' in the header.
* **Column Moving** The grid will react to Column Dragging to reorder columns.

The Custom Header Component is responsible for the following:

* **Sorting:** You will need to process user interaction for sorting. The default grid component sorts when the user clicks the header with the mouse. You may also need to display icons as the sort state of the column changes.
* **Filtering:** You do not filter via the column (you filter from inside the menu), however you may need to display icons as the filter state of the column changes.
* **Menu:** If you want the user to be able to open the column menu, you will need to manage this user interaction. The default grid component provides a button for the user to click to show the menu.
* **Anything Else:** Whatever you want, you are probably creating a custom header to add your own functionality in.

### Sorting

How you interact with the user for sorting (e.g. listening for mouse clicks) is up to you. The grid helps you by providing column state and events for getting and setting the sort.

After the user requests a sort, you should call ONE of the following:

{% if isFramework("javascript", "angular", "vue") %}
1. `params.progressSort(multiSort)`: Call this method to progress the sort on the column to the next stage. This uses the grid logic to determine the next sort stage (eg 'descending' normally follows 'ascending').
1. `params.setSort(direction, multiSort)`: If you don't want to use the grid's logic for working out the next sort state, use this to set the sort to a specific state.
{% /if %}

{% if isFramework("react") %}
1. `props.progressSort(multiSort)`: Call this method to progress the sort on the column to the next stage. This uses the grid logic to determine the next sort stage (eg 'descending' normally follows 'ascending').
1. `props.setSort(direction, multiSort)`: If you don't want to use the grid's logic for working out the next sort state, use this to set the sort to a specific state.
{% /if %}

{% if isFramework("javascript") %}
```js
// option 1) tell the grid when you want to progress the sorting
myHeaderElement.addEventListener('click', function(event) {
    // in this example, we do multi sort if Shift key is pressed
    params.progressSort(event.shiftKey);
});

// or option 2) tell the grid when you want to set the sort explicitly
// button that always sorts ASCENDING
mySortAscButton.addEventListener('click', function(event) {
    params.setSort('asc', event.shiftKey);
});

// button that always sorts DESCENDING
mySortDescButton.addEventListener('click', function(event) {
    params.setSort('desc', event.shiftKey);
});
```
{% /if %}

{% if isFramework("angular", "vue") %}
```js
// option 1) tell the grid when you want to progress the sorting
onSortClicked(event) {
     // in this example, we do multi sort if Shift key is pressed
    this.params.progressSort(event.shiftKey);
};

// or option 2) tell the grid when you want to set the sort explicitly
// button that always sorts ASCENDING
onSortAscClicked(event) {
    this.params.setSort('asc', event.shiftKey);
};

// button that always sorts DESCENDING
onSortDescClicked(event) {
    this.params.setSort('desc', event.shiftKey);
};
```
{% /if %}

{% if isFramework("react") %}
```js
// option 1) tell the grid when you want to progress the sorting
onSortClicked(event) {
     // in this example, we do multi sort if Shift key is pressed
    props.progressSort(event.shiftKey);
};

// or option 2) tell the grid when you want to set the sort explicitly
// button that always sorts ASCENDING
onSortAscClicked(event) {
    props.setSort('asc', event.shiftKey);
};

// button that always sorts DESCENDING
onSortDescClicked(event) {
    props.setSort('desc', event.shiftKey);
};
```
{% /if %}

To know when a column's sort state has changed (e.g. when to update your icons), you should listen for the `sortChanged` event on the column.

```js
// listen to the column for sort events
column.addEventListener('sortChanged', function() {

    // get sort state from column
    var sort = column.getSortDef()?.direction;
    console.log('sort state of column is ' + sort); // prints one of ['asc',desc',null]

    // then do what you need, e.g. set relevant icons visible
    var sortingAscending = sort==='asc';
    var sortingDescending = sort==='desc';
    var notSorting = !sortingAscending && !sortingDescending;
    // how you update your GUI accordingly is up to you
});

// don't forget to remove your listener in your destroy code
```

### Filtering

The header doesn't normally initiate filtering. If it does, use the standard grid API to set the filter. The header will typically display icons when the filter is applied. To know when to show a filter icon, listen to the column for `filterChanged` events.

```js
// listen to the column for filter events
column.addEventListener('filterChanged', function() {
    // when filter changes on the col, this will print one of [true,false]
    console.log('filter of column is ' + column.isFilterActive());
});

// don't forget to remove your listener in your destroy code
```

### Menu

How you get the user to ask for the column menu is up to you. When you want to display the menu, call the `params.showColumnMenu()` callback. The callback takes the HTML element for the button so that it can place the menu over the button (so the menu appears to drop down from the button).

{% if isFramework("javascript") %}
```js
myMenuButton.addEventListener('click', function() {
    params.showColumnMenu(myMenuButton);
});
```
{% /if %}

{% if isFramework("vue") %}
```js
onMenuClicked() {
    this.params.showColumnMenu(this.$refs.menuButton);
});
```
{% /if %}

{% if isFramework("angular") %}
```js
onMenuClicked() {
    this.params.showColumnMenu(this.menuButton.nativeElement);
});
```
{% /if %}

{% if isFramework("react") %}
```js
onMenuClicked() {
    props.showColumnMenu(refButton.current);
});
```
{% /if %}

### Refreshing Headers

If you are creating your own [Header Components](./column-headers/) then you will need to be aware of
how Header Components are refreshed.

All Header Components that still exist after the new Column Definitions are applied (in other words, the Column still
exists after the update, it was not removed) {% if isFramework("react") %}will be re-rendered.{% else/ %}will have its `refresh` method called.{% /if %}



{% if isFramework("react") %}
It is up to the Header Component to update based on any changes it may find in the Column Definition.
{% else/ %}
It is the responsibility of the Header Component to inspect the Column Definition for relevant changes and update itself if needed. If the refresh was successful then `true` should be returned. If the refresh was not successful then `false` should be returned. If `false` is returned, then the grid will destroy and recreate the component. This pattern is consistent with the `refresh` method of Cell Renderers.
{% /if %}

The example below demonstrates refreshing of the headers. Note the following:

* Each column is configured to use a custom Header Component.
* The Header Component logs to the console when its lifecycle methods/functions are called.
* Toggling between 'Upper Header Names' and 'Lower Header Names' causes the Header Component to refresh.
* Toggling between 'Filter On' and 'Filter Off' causes the Header Component to refresh. {% if not(isFramework("react")) %}The Header Component returns `false` which results in the component getting destroyed and recreated.{% /if %}
* Toggling between 'Resize On' and 'Resize Off' causes the Header Component to refresh. However there is no change to the Header Component as it doesn't depend on resize - the resize UI is provided by the grid.

{% gridExampleRunner title="Refresh Headers" name="refresh-headers" /%}




### Custom Props

On top of the props provided by the grid, you can also provide your own parameters. 
This is useful if you want to allow configuring the header component. For example, you might have a header component for formatting currency which also requires the currency symbol to be provided.

{% if isFramework("javascript", "angular", "react") %}
```js
colDef = {
    ...
    headerComponent: MyHeaderComponent;
    headerComponentParams : {
        currencySymbol: '£' // the pound symbol will be placed into params
    }
}
```
{% /if %}

{% if isFramework("vue") %}
```js
colDef = {
    ...
    headerComponent: 'MyHeaderComponent';
    headerComponentParams : {
        currencySymbol: '£' // the pound symbol will be placed into params
    }
}
```
{% /if %}

### Keyboard Navigation

When using Custom Header Components, the Custom Header Component is responsible for implementing support for keyboard navigation among its focusable elements. This is why by default, focusing a grid header with a Custom Header Component will focus the entire cell instead of any of the elements inside.

Adding support for keyboard navigation and focus requires a custom `suppressHeaderKeyboardEvent` function in grid options. See [Suppress Keyboard Events](./keyboard-navigation/#suppress-keyboard-events).

An example of this is shown below, enabling keyboard navigation through the custom header elements when pressing {% kbd "⇥ Tab" /%} and {% kbd "⇧ Shift" /%}+{% kbd "⇥ Tab" /%}:

* Click on the top left `Athlete` header, press the {% kbd "⇥ Tab" /%} key and notice that the button, textbox and link in the `Country` header can be tabbed into. At the end of the cell elements, the tab focus moves to the next `Age` header cell
* Use {% kbd "⇧ Shift" /%}+{% kbd "⇥ Tab" /%} to navigate in the reverse direction

The `suppressHeaderKeyboardEvent` callback is used to capture tab events and determine if the user is tabbing forward or backwards. It also suppresses the default behaviour of moving to the next cell if tabbing within the child elements.

If the focus is at the beginning or the end of the cell children and moving out of the cell, the keyboard event is not suppressed, so focus can move between the children elements. Also, when moving backwards, the focus needs to be manually set while preventing the default behaviour of the keyboard press event.

{% gridExampleRunner title="Custom Header Keyboard Navigation" name="header-component-keyboard-navigation" /%}

### Dynamic Tooltips

When using Custom Header Components it might be necessary to have a better control of how `Tooltips` are added instead of simply using the `headerTooltip` config. For this purpose, we provide the `setTooltip` method.
{% if isFramework("javascript", "angular", "vue") %}
{% interfaceDocumentation interfaceName="IHeaderParams" names=["setTooltip"] /%}
{% /if %}

{% if isFramework("react") %}
{% interfaceDocumentation interfaceName="CustomHeaderProps" names=["setTooltip"] /%}
{% /if %}

The example below demonstrates using the Dynamic Tooltips with a Custom Header Component.
* Note that only Column Headers where the text is not fully displayed will show tooltips.

{% gridExampleRunner title="Header Tooltip" name="dynamic-tooltips" /%}

### Touch Support

See the [Touch](./touch/) documentation for how the grid will handle touch support, particularly for [Touch Events](./touch/#custom-header-components).

## Tooltips

Tooltips can be added to the Column Header by using either the `headerTooltipValueGetter`, or `headerTooltip` property of the `ColDef`.

{% apiDocumentation source="column-properties/properties.json" section="header" names=["headerTooltipValueGetter", "headerTooltip"] /%}

The example below demonstrates using both `headerTooltipValueGetter` and `headerTooltip` properties to set tooltips in the grid columns.

{% gridExampleRunner title="Header Tooltip" name="header-tooltip" /%}

## Text Orientation

By default, the text label for the header is display horizontally, i.e. as normal readable text. To display the text in another orientation you have to provide your own CSS to change the orientation and also provide the adequate header heights using the appropriate grid property.

The following example shows how you can provide a unique look and feel to the headers. Note that:

* The header heights have all been changed via grid options:

```{% frameworkTransform=true  %}
    const gridOptions = {
        // Group columns
        groupHeaderHeight: 75,
        // Label columns
        headerHeight: 150,
        // Floating filter
        floatingFiltersHeight: 50,
        // Pivoting, requires turning on pivot mode. Label columns
        pivotHeaderHeight: 100,
        // Pivoting, requires turning on pivot mode. Group columns
        pivotGroupHeaderHeight: 50,
    }
```

* The grouped column header `Athlete Details` has a specific style applied to it to make it bigger. Note that the style is slightly different depending if pivoting or not:

```css
.ag-pivot-off .ag-header-group-cell {
    font-size: 50px;
    color: red;
}

.ag-pivot-on .ag-header-group-cell {
    font-size: 25px;
    color: green;
}
```

* The column labels have CSS applied to them so they are displayed vertically.

```css
.ag-header-cell-label {
    /* Necessary to allow for text to grow vertically */
    height: 100%;
    padding: 0 !important;
}

.ag-header-cell-label .ag-header-cell-text {
    /* Force the width corresponding to how much width
    we need once the text is laid out vertically */
    width: 30px;
    transform: rotate(90deg);
    margin-top: 50px;
    /* Since we are rotating a span */
    display: inline-block;
}
```

* The floating filters are using a much bigger area and the font used is bigger and bolder.

```css
.ag-floating-filter-body input {
    height: 49px;
}

.ag-floating-filter-button {
    margin-top: -49px;
}

.ag-floating-filter-button button {
    height: 49px
}

.ag-floating-filter-body input {
    font-size: 15px;
    font-weight: bold;
}
```

* The styling of the column labels have also been tweaked depending if pivoting or not.

```css
.ag-pivot-off .ag-header-cell-label {
    color: #8a6d3b;
}

.ag-pivot-on .ag-header-cell-label {
    color: #1b6d85;
    font-weight: bold;
}
```

{% gridExampleRunner title="Header Height and Text Orientation" name="text-orientation" /%}

